﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Plugins
{
    public partial class Form1 : Form
    {
        private Point latestLocation;
        private string format1 = "插件运行总量:{0}";
        private int pluginHeight = 52;
        private bool autostart;
        public Form1(bool autostart)
        {
            InitializeComponent();
            this.autostart = autostart;
            if(autostart)
            {
                this.WindowState = FormWindowState.Minimized;
                this.Visible = false;
            }
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.CacheText | ControlStyles.OptimizedDoubleBuffer, true);
            this.Height = 320;
            this.StartPosition = FormStartPosition.CenterScreen;
            PluginManager.Initial();
            if (PluginManager.Plugins.Count < 6)
                vScrollBar1.Visible = false;
            LoadPluginList(PluginManager.Plugins);
            var tempPlugin = PluginManager.Plugins.FirstOrDefault();
            if (tempPlugin != null)
                RefreshPluginIntroduction(0, tempPlugin.Name, tempPlugin.Version, tempPlugin.Description);
            KeepRefreshRunningObjects();
            vScrollBar1.Maximum = latestLocation.Y - pluginHeight;
            vScrollBar1.LargeChange = pluginHeight * 5;
            vScrollBar1.SmallChange = pluginHeight;
            vScrollBar1.Scroll += VScrollBar1_Scroll;
            this.MouseWheel += Form1_MouseWheel;
            this.ContextMenuStrip = InitStrip();
            SetIcon();
        }

        private void SetIcon()
        {
            string[] path = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory).Where(s => s.Contains("appicon")).ToArray();
            Bitmap bitmap = null;
            int index = 0;
            while (index < path.Length)
            {
                try
                {
                    bitmap = (Bitmap)Image.FromFile(path[index]);
                    break;
                }
                catch (Exception ex)
                {
                    index++;
                }
            }
            if (bitmap == null)
            {
                bitmap = new Bitmap(100, 500);
                bitmap.Save(Application.StartupPath +"\\appicon.jpeg");
            }
            this.Icon = Icon.FromHandle(bitmap.GetHicon());
        }
        private ContextMenuStrip InitStrip()
        {
            ContextMenuStrip strip = new ContextMenuStrip();
            strip.Items.Add("设置").Click += Form1_Click2;
            strip.Items.Add("关于").Click += Form1_Click;
            strip.Items.Add("退出").Click += Form1_Click1;
            return strip;
        }

        private void Form1_Click2(object sender, EventArgs e)
        {
            FormSettings form = new FormSettings();
            form.ShowDialog();
        }

        private void Form1_Click1(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Form1_Click(object sender, EventArgs e)
        {
            FormAbout form = new FormAbout();
            form.ShowDialog();
        }

        private void Form1_Scroll(object sender, ScrollEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void Form1_MouseWheel(object sender, MouseEventArgs e)
        {

            int initValue = vScrollBar1.Value;
            int newValue = e.Delta < 0 ? initValue + pluginHeight : initValue - pluginHeight; ;
            newValue = newValue > 0 ? newValue : 0;
            newValue = newValue > vScrollBar1.Maximum ? vScrollBar1.Maximum : newValue;
            vScrollBar1.Value = newValue;
            VScrollBar1_Scroll(this, new ScrollEventArgs(ScrollEventType.SmallIncrement, initValue, vScrollBar1.Value, ScrollOrientation.VerticalScroll) { });
        }

        private void VScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            if (e.Type == ScrollEventType.Last)
                MessageBox.Show("Last:" + e.NewValue);
            if (e.NewValue == e.OldValue)
                return;
            foreach (Control i in this.Controls)
            {
                if (i is UCPlugin)
                {
                    i.Location = new Point(i.Location.X, i.Location.Y + e.OldValue - e.NewValue);
                }
            }
        }
        private void LoadPluginList(List<PluginObject> plugins)
        {
            foreach (var i in plugins)
            {
                UCPlugin plugin = new UCPlugin(i, pluginHeight, RefreshPluginIntroduction);
                plugin.Location = latestLocation;
                latestLocation = new Point(0, latestLocation.Y + plugin.Height);
                Controls.Add(plugin);
            }
        }

        public void RefreshPluginIntroduction(int count, string name, string version, string description)
        {
            labCount.Text = string.Format("{0}实例个数:{1}   版本:{2}  {3}", name, count, version, description);
        }

        public async void KeepRefreshRunningObjects()
        {
            await Task.Run(() =>
            {
                while (true)
                {
                    Monitor.Enter(PluginManager.obj);
                    try
                    {
                        for (int i = 0; i < PluginManager.RunningPlugins.Count(); i++)
                        {
                            if (PluginManager.RunningPlugins[i].AppDomain.GetData("data-id") == null)
                            {
                                PluginManager.RunningPlugins[i].IsRun = false;
                                PluginManager.RunningPlugins.RemoveAt(i);
                                i--;
                            }
                        }
                    }
                    catch (Exception ex)
                    {

                        throw;
                    }
                    if (this.IsHandleCreated)
                        Invoke(new MethodInvoker(Refresh));
                    Thread.Sleep(1200);
                    Monitor.Exit(PluginManager.obj);
                }
            });
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            e.Cancel = true;
            this.Visible = false;
            base.OnClosing(e);
        }
        public override void Refresh()
        {
            this.Invalidate(true);
            labTotalCount.Text = string.Format(format1, PluginManager.RunningPlugins.Count);
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            //drawing
            Graphics g = e.Graphics;
            g.DrawLine(Pens.LightGray, new Point(0, 1), new Point(this.Width, 1));

            //other
            labTotalCount.Text = string.Format(format1, PluginManager.RunningPlugins.Count);
        }
    }
}
